package com.byd.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.byd.system.domain.SysDept;
import com.byd.system.domain.SysPost;
import com.byd.system.domain.SysRole;
import com.byd.system.domain.SysUser;
import com.byd.system.domain.model.TreeSelect;
import com.byd.system.domain.vo.SysDeptVo;
import com.byd.system.domain.vo.SysPostVo;
import com.byd.system.domain.vo.SysRoleVo;
import com.byd.system.enums.GroupType;
import com.byd.system.mapper.SysDeptMapper;
import com.byd.system.mapper.SysPostMapper;
import com.byd.system.mapper.SysRoleMapper;
import com.byd.system.mapper.SysUserMapper;
import com.byd.system.page.PageBean;
import com.byd.web.service.IActivitiService;
import com.byd.web.utils.StaticUtils;
import com.byd.web.utils.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ActivitiServiceImpl implements IActivitiService {
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private SysDeptMapper deptMapper;
    @Resource
    private SysPostMapper postMapper;
    @Resource
    private SysRoleMapper roleMapper;

    @Autowired
    private JavaMailSender mailSender;

    @Override
    public List<SysPostVo> getPostList() {
        List<SysPostVo> postList = new LinkedList<>();
        List<SysPost> list = postMapper.getList();

        if (CollectionUtil.isNotEmpty(list)) {
            for (SysPost post : list) {
                SysPostVo option = new SysPostVo();
                option.setId(post.getPostId());
                option.setName(post.getPostName());
                postList.add(option);
            }
        }

        return postList;
    }

    @Override
    public List<SysPostVo> getPostByDept(Long deptId) {
        List<SysPostVo> postList = new LinkedList<>();
        List<SysPost> list = postMapper.getPostByDept(deptId);

        if (CollectionUtil.isNotEmpty(list)) {
            for (SysPost post : list) {
                SysPostVo option = new SysPostVo();
                option.setId(post.getPostId());
                option.setName(post.getPostName());
                postList.add(option);
            }
        }

        return postList;
    }

    @Override
    public List<SysRoleVo> getRoleList() {
        List<SysRoleVo> roleList = new LinkedList<>();
        List<SysRole> list = roleMapper.getList();

        if (CollectionUtil.isNotEmpty(list)) {
            for (SysRole role : list) {
                SysRoleVo option = new SysRoleVo();
                option.setId(role.getRoleId());
                option.setName(role.getRoleName());
                roleList.add(option);
            }
        }

        return roleList;
    }

    @Override
    public List<SysDeptVo> getDeptList() {
        List<SysDeptVo> deptList = new LinkedList<>();
        List<SysDept> list = deptMapper.getList();

        if (CollectionUtil.isNotEmpty(list)) {
            for (SysDept dept : list) {
                if (0L != dept.getParentId()) {
                    SysDeptVo option = new SysDeptVo();
                    option.setId(dept.getDeptId());
                    option.setName(dept.getDeptName());
                    SysDept parentDept = deptMapper.selectById(dept.getParentId());
                    option.setParentName(parentDept.getDeptName());
                    deptList.add(option);
                }
            }
        }

        return deptList;
    }

    @Override
    public List<SysDept> selectDeptList(SysDept dept) {
        return deptMapper.selectDeptList(dept);
    }

    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts) {
        List<SysDept> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public PageBean<SysUser> queryUserPage(Integer pageNum, Integer pageSize, Integer groupType, String groupId) {
        PageBean<SysUser> pageBean = new PageBean<>();
        PageHelper.startPage(pageNum, pageSize);
        List<SysUser> userList = null;

        if (Objects.equals(GroupType.DEPT.getValue(), groupType)) {
            userList = userMapper.selectByDeptId(Long.parseLong(groupId));
        } else if (Objects.equals(GroupType.ROLE.getValue(), groupType)) {
            userList = userMapper.selectByRoleId(Long.parseLong(groupId));
        } else if (Objects.equals(GroupType.POST.getValue(), groupType)) {
            String[] groupIds = groupId.split(":");

            if (groupIds.length == 2) {
                Long deptId = Long.parseLong(groupIds[0]);
                Long postId = Long.parseLong(groupIds[1]);
                Map<String, Object> params = new HashMap<>();
                params.put("deptId", deptId);
                params.put("postId", postId);
                userList = userMapper.selectByCond(params);
            } else {
                userList = userMapper.selectByPostId(Long.parseLong(groupId));
            }
        } else {
            userList = userMapper.getList();
        }

        Page<SysUser> page = (Page<SysUser>) userList;
        pageBean.setRows(page.getResult());
        pageBean.setTotal(page.getTotal());

        return pageBean;
    }

    @Override
    public boolean sendEmail(List<String> ids) {
        Long[] userIds = ids.stream().map(Long::parseLong).toArray(Long[]::new);
        List<SysUser> userList = userMapper.selectBatchIds(userIds);
        // 填充excel模板
        String fileName = StaticUtils.buildFileName("测试", new Date());
        try {
            StaticUtils.buildStaticHtml(userList, fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String contentExcel = StaticUtils.readStaticHtml(fileName);

        for (SysUser toUser : userList) {
            MimeMessage message = mailSender.createMimeMessage();
            try {
                if (StringUtils.isNotBlank(toUser.getEmail())) {
                    MimeMessageHelper helper = new MimeMessageHelper(message, true, StandardCharsets.UTF_8.name());
                    // 发送方
                    helper.setFrom("hewei090918@126.com");
                    // 接收方
                    helper.setTo(toUser.getEmail());
                    helper.setSubject("你好：" + toUser.getNickName());
                    // 主题内容，true表示以HTML格式发送邮件
                    helper.setText(contentExcel, true);
                    mailSender.send(message);
                    log.info("========邮件发送成功========");
                }
            } catch (MessagingException e) {
                throw new RuntimeException("邮件发送失败", e);
            }
        }
        StaticUtils.delete(fileName);
        return true;
    }

    private List<SysDept> buildDeptTree(List<SysDept> depts) {
        List<SysDept> returnList = new ArrayList<SysDept>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysDept dept : depts) {
            tempList.add(dept.getDeptId());
        }
        for (SysDept dept : depts) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SysDept> list, SysDept t) {
        // 得到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            } else {
                List<SysUser> userList = userMapper.selectByDeptId(tChild.getDeptId());
                List<SysDept> userDepts = new LinkedList<>();

                for (SysUser user : userList) {
                    SysDept userDept = new SysDept();
                    userDept.setDeptId(user.getUserId());
                    userDept.setDeptName(user.getNickName());
                    userDepts.add(userDept);
                }
                tChild.setChildren(userDepts);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
        List<SysDept> tlist = new ArrayList<SysDept>();
        Iterator<SysDept> it = list.iterator();
        while (it.hasNext()) {
            SysDept n = (SysDept) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDept> list, SysDept t) {
        return getChildList(list, t).size() > 0;
    }

}
